xenpaging: optimize p2m_mem_paging_populate
authorKeir Fraser <keir@xen.org>
Fri, 26 Nov 2010 14:22:11 +0000 (14:22 +0000)
committerKeir Fraser <keir@xen.org>
Fri, 26 Nov 2010 14:22:11 +0000 (14:22 +0000)
p2m_mem_paging_populate will always put another request in the ring.
To reduce pressure on the ring, place only required requests in the
ring.  If the gfn was already processed by another thread, and the
current vcpu does not need to be paused, p2m_mem_paging_resume will do
nothing with the request.  And also xenpaging will drop the request if
the vcpu does not need a wakeup.

Signed-off-by: Olaf Hering <olaf@aepfle.de>
xen/arch/x86/mm/p2m.c

index d7da4ad1f2509549520fe2b4ec1abf125bb683f4..9620866ef3593c46de53f66e112741626a88d91a 100644 (file)
@@ -2757,12 +2757,12 @@ void p2m_mem_paging_populate(struct p2m_domain *p2m, unsigned long gfn)
     p2m_type_t p2mt;
     struct domain *d = p2m->domain;
 
-    memset(&req, 0, sizeof(req));
-
     /* Check that there's space on the ring for this request */
     if ( mem_event_check_ring(d) )
         return;
 
+    memset(&req, 0, sizeof(req));
+
     /* Fix p2m mapping */
     /* XXX: It seems inefficient to have this here, as it's only needed
      *      in one case (ept guest accessing paging out page) */
@@ -2781,6 +2781,11 @@ void p2m_mem_paging_populate(struct p2m_domain *p2m, unsigned long gfn)
         vcpu_pause_nosync(v);
         req.flags |= MEM_EVENT_FLAG_VCPU_PAUSED;
     }
+    else if ( p2mt != p2m_ram_paging_out && p2mt != p2m_ram_paged )
+    {
+        /* gfn is already on its way back and vcpu is not paused */
+        return;
+    }
 
     /* Send request to pager */
     req.gfn = gfn;